/**
 * Project Name:umale-maintenance
 * File Name:ProxyUtils
 * Package Name:com.xuhaowei.utils
 * Date: 2020/3/4 下午3:41
 * Copyright (c) 2018, Neoglory-umale All Rights Reserved.
 */
package com.xuhaowei.utils;

import com.xuhaowei.mvcframework.myannotation.XUAutowired;
import com.xuhaowei.mvcframework.myannotation.XUCompoment;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @ClassName ProxyUtils
 * @Description TODO
 * @Author xuhaowei
 * @Date 2020/3/4 下午3:41
 * @Version 1.0.0
 * @since JDK 1.8
 */

@XUCompoment
public class ProxyUtils {

    @XUAutowired
    TransactionManager transactionManager;

    public Object getProxyObject(final Object obj, Boolean interfaceFlag, final Boolean transactionalFlag, final Class[] exceptionClass) {
        //如果是实现过接口的标志,进行jdk增强
        if (interfaceFlag) {
            // 获取代理对象
            return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            Object result = null;

                            try {
                                if (transactionalFlag) {
                                    // 开启事务(关闭事务的自动提交)
                                    transactionManager.beginTransaction();
                                }

                                result = method.invoke(obj, args);

                                // 提交事务
                                if (transactionalFlag) {
                                    transactionManager.commit();
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                // 回滚事务
                                if (transactionalFlag) {
                                    for (Class aClass : exceptionClass) {
                                        Object o = aClass.newInstance();
                                        if (e.getClass().isInstance(o)) {
                                            transactionManager.rollback();
                                            break;
                                        }
                                    }

                                }

                                // 抛出异常便于上层servlet捕获
                                throw e;

                            }

                            return result;
                        }
                    });
        } else {
            return Enhancer.create(obj.getClass(), new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    Object result = null;
                    try {
                        // 开启事务(关闭事务的自动提交)
                        if (transactionalFlag) {
                            transactionManager.beginTransaction();
                        }

                        result = method.invoke(obj, objects);

                        // 提交事务
                        if (transactionalFlag) {
                            transactionManager.commit();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        // 回滚事务
                        if (transactionalFlag) {
                            if (transactionalFlag) {
                                for (Class aClass : exceptionClass) {
                                    Object object = aClass.newInstance();
                                    if (e.getClass().isInstance(object)) {
                                        transactionManager.rollback();
                                        break;
                                    }
                                }

                            }
                        }

                        // 抛出异常便于上层servlet捕获
                        throw e;

                    }
                    return result;
                }
            });
        }
    }
}